package com.wn.network.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.ToastUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

/**
 * @Author: wn
 * @Date: 2024/8/8 16:39
 * @Description: viewModel基类 -- 调用 BaseRepository 获取 StateFlow
 * protected -- 子类中可见, 实例不可见,子类实例不可见
 *
 * 1 定义一个函数 getStateFlow 传参 -->获得 StateFlow<T?>
 * 2 BaseRepository -- callStateFlow-- 调用 getStateFlow(四个参数)
 * 3 repo实例中 定义一个 函数变量(三个参数+落地API请求)返回StateFlow<T?>
 *  函数体中调用 BaseRepository--callStateFlow(lambda 中 落地API请求 )
 * 4 BaseViewModel 定义请求 函数--callBaseRequest，函数参数为一个lambda 匿名函数
 *   该函数的参数和返回值 与 repo实例中 定义一个 函数变量 保持一致
 *   callBaseRequest 执行 返回 block() 落地 scope errorCall showLoading
 * 5 viewModel 实例 持有 repo实例
 *   vm 调用 callBaseRequest 传入 repo实例中 函数变量
 */
open class BaseViewModel : ViewModel() {
  /**
   * 是否 加载 Loading
   */
  private val _isLoading = MutableStateFlow(false)
  val loading: StateFlow<Boolean> = _isLoading

  /**
   * callBaseRequest接收一个Lambda,Lambda执行 传参，返回 StateFlow<T?>
   * @param block Function3<[@kotlin.ParameterName] CoroutineScope, [@kotlin.ParameterName] Function2<Int?, String?, Unit>?, [@kotlin.ParameterName] Function1<Boolean, Unit>?, StateFlow<T?>>
   * @param isShowLoading Boolean                           --  是否 触发弹框 函数
   * @param isGetErrorCode ((Int?, String?) -> Unit)?       --  是否获取错误码
   * @return StateFlow<T?>
   */
  protected fun <T> callBaseRequest(
    block: (
      scope: CoroutineScope,
      errorCall: ((Int?, String?) -> Unit)?,
      showLoading: ((Boolean) -> Unit)?,
    ) -> StateFlow<T?>,
    isShowLoading: Boolean = false,
    isGetErrorCode: ((Int?, String?) -> Unit)? = null,
  ): StateFlow<T?> {
    var showLoading: ((Boolean) -> Unit)? = null
    if (isShowLoading) showLoading = { _isLoading.value = it }

    return block(
      viewModelScope,
      isGetErrorCode ?: { code, msg -> ToastUtils.showShort("API请求失败,错误码: $code,错误信息: $msg") },
      showLoading,
    )
  }
  /**
   * viewModel 中 获取 StateFlow, 落地 scope,error,loading -- 传递 lambda
   * requestCall -- { 只需要 viewModel 根据 repo提供 APi 即可 }
   * @return StateFlow<T?>
   */
/*
  protected fun <T> callRepo(requestCall: suspend () -> BaseResponse<T>?): StateFlow<T?> =
    baseRepository.callStateFlow(
      viewModelScope,
      { code, msg -> ToastUtils.showShort("请求失败,错误码: $code,错误信息: $msg") },
      { _isLoading.value = it },
      requestCall
    )
    */
}
// region VM 实例 demo
/*
class HomeViewModel : BaseViewModel() {
  private val repo = HomeRepo()
  fun test(): StateFlow<Int?> = callBaseRequest(repo.test)
}

class HomeRepo : BaseRepository() {
  val test: (
    scope: CoroutineScope,
    errorCall: ((Int?, String?) -> Unit)?,
    showLoading: ((Boolean) -> Unit)?,
  ) -> StateFlow<Int?> = { scope, errorCall, showLoading ->
    callStateFlow(scope, errorCall, showLoading) {
      BaseResponse(1, 1, "")
    }
  }
}
*/
// endregion
